%% @author author <author@example.com>
%% @copyright YYYY author.

%% @doc Web server for xengine.

-module(xengine_web).
-author('author <author@example.com>').

-export([start/1, stop/0, loop/2]).

%% External API

start(Options) ->
    {DocRoot, Options1} = get_option(docroot, Options),
    Loop = fun (Req) ->
                   ?MODULE:loop(Req, DocRoot)
           end,
    mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options1]).

stop() ->
    mochiweb_http:stop(?MODULE).


loop(Req, DocRoot) ->
%%    "/" ++ Path = Req:get(path),
%% error_logger:info_msg("recv a req path: ~p~n",[Req:get(path)]),
%% Result=string:tokens(Req:get(path), "/"),
%% error_logger:info_msg("Result: ~p~n",[Result]),

 case  string:tokens(Req:get(path), "/") of
  [ "dump" ] ->
   Req:ok({"text/plain",
   io_lib:format("~p~n", [Req:dump()])});

  [ "favicon.ico" ] ->
   Req:respond({404, [], ""});

  [ "codepath" ] ->
    Req:ok({"text/plain",
    io_lib:format("codepath: ~p~n", [code:get_path()])});
  
  ["rest" , Module , Fun | _Args] ->
%%   	 error_logger:info_msg("Module=~p~n",[Module]),
%%	 error_logger:info_msg("Fun=~p~n",[Fun]),
%%	 error_logger:info_msg("Args=~p~n",[Args]),
         dispatch( Req, DocRoot , list_to_atom(Module), list_to_atom(Fun) , Req:parse_post() ) ;

%%  [ "rest" , Module, Fun | Args ] ->
 %%	 error_logger:info_msg("Module=~p~n",[Module]),
 %%	 error_logger:info_msg("Fun=~p~n",[Fun]),
 %%	 error_logger:info_msg("Args=~p~n",[Args]),
%%	 dispatch(Req, DocRoot, list_to_atom(Module) , list_to_atom(Fun), Args);
  [] ->
   launch(Req, DocRoot, wdefault, do, []);

  _ ->
   Req:respond({502, [], []})
   
 end.




%% Internal API
dispatch(Req, DocRoot, Module, Fun, Elems) ->
 M = Req:get(method),
 case M of
 
  'POST' ->
%%   error_logger:info_msg("It's a post !~n"),
   launch(Req, DocRoot, Module, Fun, Elems);
%%  'GET' ->
%%   launch(Req, DocRoot, Module, Fun, Elems);
%%  'PUT' ->
%%   launch(Req, DocRoot, Module, Fun, Elems);
%%  'DELETE' ->
%%   launch(Req, DocRoot, Module, Fun, Elems);
%%  'HEAD' ->
%%   launch(Req, DocRoot, Module, Fun, Elems);
  _Any ->
   launch(Req, DocRoot, wdefault, get, [])
 end.

launch(Req, DocRoot, wcontent, Fun, Args) ->
 case catch wcontent:default(Req, DocRoot, [ Fun | Args] ) of
  {'EXIT', {Type, _Error}} ->
   Req:ok({"text/plain",  
    io_lib:format("GET Error: '~p' for '~p' ~p ~p~n~p~n", [Type, wcontent, Fun, Args, _Error])});
  _ ->
   ok
 end;
launch(Req, _DocRoot, Module, Fun, Args) ->
 case catch xengine_web_launch:launch( Module, Fun, Args) of
	 {'EXIT', {Type, _Error}} ->
	   Req:ok({"text/plain",  
	    io_lib:format("~p Error: '~p' for ~p ~p ~p~n~p~n", [Req:get(method), Type, Module, Fun, Args, _Error])});
	  Any ->
%%                error_logger:info_msg("xengine_web:result =~p~n",[Any]),
 		Req:ok({"text/plain", list_to_binary(xengine_json:encode(Any))	})
%%                Req:ok({"text/plain",   io_lib:format("~p",[Any])})
   end.  

%%launch(Req, DocRoot, Module, Fun, Args) ->
%% case catch apply(Module,Fun,parse_args(Args)) of
%%	 {'EXIT', {Type, _Error}} ->
%%	   Req:ok({"text/plain",  
%%	    io_lib:format("~p Error: '~p' for ~p ~p ~p~n~p~n", [Req:get(method), Type, Module, Fun, Args, _Error])});
%%	  Any ->
%% 		Req:ok({"text/plain", 	mochijson2:encode(Any)})
%%   end.

get_option(Option, Options) ->
    {proplists:get_value(Option, Options), proplists:delete(Option, Options)}.



%%parse_args(Args) when is_list(Args)->
%%	Fun = fun(X) ->
%%		error_logger:info_msg("X=~p~n",[X]),
%%		{ok ,Tokens } = erl_scan:string(X),
%%		{ok , Result} = erl_parse:parse_term(Tokens),
%%		error_logger:info_msg("Result=~p~n",[Result]),
%%		Result 	
%%	end,
%%	lists:foreach( Fun , Args    ).

